﻿using LJ.Abstractions.DependencyInjection.Attributes;
using LJ.Abstractions.DependencyInjection;
using LJ.Abstractions.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LJ.TaskScheduler.Hangfire.Pack;
using LJ.TaskScheduler.Abstractions.Attributes;
using Microsoft.Extensions.DependencyInjection;
using LJ.Abstractions.Reflection;

namespace LJ.TaskScheduler.Hangfire;

public class TaskSchedulerManager: ITaskSchedulerManager
{
    private readonly IServiceCollection _serviceCollection;
    private readonly IReflectionManager _reflectionManager;

    private readonly TaskSchedulerHangfirePackBuilder _taskSchedulerHangfirePackBuilder;

    public TaskSchedulerManager(IServiceCollection serviceCollection,IReflectionManager reflectionManager, TaskSchedulerHangfirePackBuilder taskSchedulerHangfirePackBuilder)
    {
        _serviceCollection = serviceCollection;
        _reflectionManager = reflectionManager;
        _taskSchedulerHangfirePackBuilder = taskSchedulerHangfirePackBuilder;

        var types = FindTypes();

        foreach (var type in types) 
        {
            _taskSchedulerHangfirePackBuilder.Add(type);
        }

        foreach (var info in _taskSchedulerHangfirePackBuilder.GetWorkerInfos()) 
        {
            _serviceCollection.AddTransient(info.Type);
        }
    }

   
    private List<Type> FindTypes()
    {
        Type[] baseTypes = [typeof(ITaskSchedulerWorker)];
        return _reflectionManager.GetTypes(type => type.IsClass && !type.IsAbstract && !type.IsInterface
            && (baseTypes.Any(b => b.IsAssignableFrom(type))) && type.HasAttribute<TaskSchedulerAttribute>());
    }
}
